﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;

public class TextureLoader : MonoBehaviour
{
    public static Texture2D LoadDDSManual(string ddsPath)
    {
        try
        {
            byte[] src = File.ReadAllBytes(ddsPath);
            byte num = src[4];
            if (num != 0x7c)
            {
                throw new Exception("Invalid DDS DXTn texture. Unable to read");
            }
            int height = (src[13] * 0x100) + src[12];
            int width = (src[0x11] * 0x100) + src[0x10];
            byte num4 = src[0x57];
            TextureFormat format = TextureFormat.DXT5;
            switch (num4)
            {
                case 0x31:
                    format = TextureFormat.DXT1;
                    break;

                case 0x35:
                    format = TextureFormat.DXT5;
                    break;
            }
            int srcOffset = 0x80;
            byte[] dst = new byte[src.Length - srcOffset];
            Buffer.BlockCopy(src, srcOffset, dst, 0, src.Length - srcOffset);
            FileInfo info = new FileInfo(ddsPath);
            Texture2D textured = new Texture2D(width, height, format, false);
            textured.LoadRawTextureData(dst);
            textured.Apply();
            textured.name = info.Name;
            return textured;
        }
        catch (Exception)
        {
            Debug.LogError("Error: Could not load DDS");
            return new Texture2D(8, 8);
        }
    }

    public static Texture2D LoadTexture(string fn, bool normalMap = false)
    {
        if (File.Exists(fn))
        {
            switch (Path.GetExtension(fn).ToLower())
            {
                case ".png":
                case ".jpg":
                {
                    Texture2D tex = new Texture2D(1, 1);
                    tex.LoadImage(File.ReadAllBytes(fn));
                    if (normalMap)
                    {
                        SetNormalMap(ref tex);
                    }
                    return tex;
                }
                case ".dds":
                {
                    Texture2D textured2 = LoadDDSManual(fn);
                    if (normalMap)
                    {
                        SetNormalMap(ref textured2);
                    }
                    return textured2;
                }
                case ".tga":
                {
                    Texture2D textured3 = LoadTGA(fn);
                    if (normalMap)
                    {
                        SetNormalMap(ref textured3);
                    }
                    return textured3;
                }
            }
            Debug.Log("texture not supported : " + fn);
        }
        return null;
    }

    public static Texture2D LoadTGA(Stream TGAStream)
    {
        using (BinaryReader reader = new BinaryReader(TGAStream))
        {
            reader.BaseStream.Seek(12L, SeekOrigin.Begin);
            short width = reader.ReadInt16();
            short height = reader.ReadInt16();
            int num3 = reader.ReadByte();
            reader.BaseStream.Seek(1L, SeekOrigin.Current);
            Texture2D textured = new Texture2D(width, height);
            Color32[] colors = new Color32[width * height];
            if (num3 == 0x20)
            {
                for (int i = 0; i < (width * height); i++)
                {
                    byte b = reader.ReadByte();
                    byte g = reader.ReadByte();
                    byte r = reader.ReadByte();
                    byte a = reader.ReadByte();
                    colors[i] = new Color32(r, g, b, a);
                }
            }
            else
            {
                if (num3 != 0x18)
                {
                    throw new Exception("TGA texture had non 32/24 bit depth.");
                }
                for (int j = 0; j < (width * height); j++)
                {
                    byte num10 = reader.ReadByte();
                    byte num11 = reader.ReadByte();
                    byte num12 = reader.ReadByte();
                    colors[j] = new Color32(num12, num11, num10, 1);
                }
            }
            textured.SetPixels32(colors);
            textured.Apply();
            return textured;
        }
    }

    public static Texture2D LoadTGA(string fileName)
    {
        using (FileStream stream = File.OpenRead(fileName))
        {
            return LoadTGA(stream);
        }
    }

    public static void SetNormalMap(ref Texture2D tex)
    {
        Color[] pixels = tex.GetPixels();
        for (int i = 0; i < pixels.Length; i++)
        {
            Color color = pixels[i];
            color.r = pixels[i].g;
            color.a = pixels[i].r;
            pixels[i] = color;
        }
        tex.SetPixels(pixels);
    }
}

